import Table from "@/components/Table";
import { Space, Button, message, Modal, Upload, Form, Input, FormInstance, Tag, Radio, RadioChangeEvent, Card, InputNumber, Select } from "antd";
import '@/assets/styles/buttonStyles.css';
import '@/views/system/user/user.css';
import { DataType, ColumnsType } from "@/types/model";
import { useEffect, useState } from "react";
import { getCookie } from "@/utils/cookies";
import React from "react";
import { useNavigate } from "react-router-dom";
import { localStorageGetItem } from "@/utils/localStorage";
import baseUrl from '@/config'
import { PlusOutlined } from '@ant-design/icons';
import type { RcFile, UploadProps } from 'antd/es/upload';
import type { UploadFile } from 'antd/es/upload/interface';
import { Image } from 'antd';
import Meta from "antd/es/card/Meta";
import LoadingIndicator from '@/components/loading';

const getBase64 = (file: RcFile): Promise<string> =>
  new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.readAsDataURL(file);
    reader.onload = () => resolve(reader.result as string);
    reader.onerror = (error) => reject(error);
  });

const Model: React.FC = () => {
  const [pageLoading, setPageLoading] = useState(true);
  const [data, setData] = useState<DataType[]>([]);
  const [form] = Form.useForm();
  const [isModalOpen, setIsModalOpen] = useState(false);
  const [selInfo, setSelInfo] = useState('');
  const [selInfo2, setSelInfo2] = useState('');
  const [listNum, setListNum] = useState(0);
  const [editId, setEditId] = useState(0);
  const [editInfo, setEditInfo] = useState('');
  // 定义时序预测模型测试所需的属性
  const [zoneTemp, setZoneTemp] = useState(0);
  const [zoneWeather, setZoneWeather] = useState(0);
  const [zonePower, setZonePower] = useState(0);
  const [isHoliday, setIsHoliday] = useState(0);
  const [isWeekend, setIsWeekend] = useState(0);
  const [nearbyZoneNum, setNearbyZoneNum] = useState(0);
  const [k1ZoneFlow, setK1ZoneFlow] = useState(0);
  const [k2ZoneFlow, setK2ZoneFlow] = useState(0);
  const [k3ZoneFlow, setK3ZoneFlow] = useState(0);

  const [lstmModalOpen, setLstmModalOpen] = useState(false);

  const handleLstmTestOk = async () => {
    setLoadings([true]);
    setBtnTxt("测试中")
    if (editInfo === '') {
      setLoadings([false]);
      setBtnTxt("开始测试");
      message.warning('请输入测试备注!', 2);
      return;
    }
    try {
      const response = await fetch(baseUrl + '/back/model/testModel', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          'token': `${getCookie('token')}`
        },
        body: JSON.stringify({
          modelId: editId,
          modelTestText: editInfo,
          modelTester: localStorageGetItem('userName'),
          zoneTemp: zoneTemp,
          zoneWeather: zoneWeather,
          zonePower: zonePower,
          isHoliday: isHoliday,
          isWeekend: isWeekend,
          nearbyZoneNum: nearbyZoneNum,
          k1ZoneFlow: k1ZoneFlow,
          k2ZoneFlow: k2ZoneFlow,
          k3ZoneFlow: k3ZoneFlow
        })
      });

      if (response.ok) {
        // 请求成功
        const data = await response.json();
        // 处理响应数据
        if (data.code === 200) {
          message.success(data.msg, 2)
          const dectectRes = JSON.parse(data.data);
          const details = dectectRes.details;
          let bs64 = []
          for (const bs of details) {
            bs64.push(bs.image_base64)
          }
          setBase64Array(bs64);
          let lgs = []
          const resLogs = dectectRes.logs;
          for (const lg of resLogs) {
            const tlg = lg.split(':')
            lgs.push(tlg[tlg.length - 1])
          }
          setLogResArray(lgs)
          setShowResImages(true)
        }
        else {
          message.warning(data.msg, 2);
        }
      } else {
        // 请求失败
        console.error('Error:', response.status);
      }
    } catch (error) {
      console.error('Error:', error);
    }
    setBtnTxt("开始测试");
    setLoadings([false]);
    setLstmModalOpen(false);
  };

  const handleLstmTestCancel = async () => {
    setLstmModalOpen(false);
  };

  const handleLstmInfo1Change = (value: number | null) => {
    setZoneTemp(value ?? 0.0);
  };

  const handleLstmInfo2Change = (value: number | null) => {
    setZoneWeather(value ?? 0);
  };

  const handleLstmInfo3Change = (value: number | null) => {
    setZonePower(value ?? 0.0);
  };

  const handleLstmInfo4Change = (value: number | null) => {
    setIsHoliday(value ?? 0);
  };

  const handleLstmInfo5Change = (value: number | null) => {
    setIsWeekend(value ?? 0);
  };

  const handleLstmInfo6Change = (value: number | null) => {
    setNearbyZoneNum(value ?? 0);
  };

  const handleLstmInfo7Change = (value: number | null) => {
    setK1ZoneFlow(value ?? 0);
  };

  const handleLstmInfo8Change = (value: number | null) => {
    setK2ZoneFlow(value ?? 0);
  };

  const handleLstmInfo9Change = (value: number | null) => {
    setK3ZoneFlow(value ?? 0);
  };

  const showModalEdit = (record: DataType, e?: React.MouseEvent<HTMLElement, MouseEvent>) => {
    if (e) {
      setBtnTxt("开始测试");
      setEditId(record.id);
      if (record.modelType === '时序预测') {
        setLstmModalOpen(true)
      }
      else {
        setIsModalOpen(true);
      }
    }
  };

  const handleCancel = () => {
    setIsModalOpen(false);
  };


  const navigateTo = useNavigate();
  useEffect(() => {
    // 判断是否有token，检测用户是否已登录，如果未登录，给出提示，并将其跳转到登录页
    if (getCookie('token') == null) {
      message.error("尚未登录，不得访问！", 1);
      navigateTo("/login");
      return;
    }
    fetchData(); // 调用获取数据的函数
  }, []);


  const fetchData = async () => {
    try {
      const response = await fetch(baseUrl + '/back/model/getModelList', {
        method: 'GET',
        headers: {
          'Content-Type': 'application/json',
          'token': `${getCookie('token')}`
        },
      });
      setPageLoading(false);
      if (response.ok) {
        // 请求成功
        const data = await response.json();
        // 处理响应数据
        if (data.msg === '操作成功') {
          const dataWithKeys = data.data.map((item: { id: { toString: () => any; }; }) => ({ ...item, key: item.id.toString() }));
          setData(dataWithKeys);
          setListNum(dataWithKeys.length);
        }
        else {
          message.warning(data.msg, 1);
        }
      } else {
        // 请求失败
        console.error('Error:', response.status);
      }
    } catch (error) {
      console.error('Error:', error);
    }
  };

  const [loadings, setLoadings] = useState<boolean[]>([]);
  const [testBthTxt, setBtnTxt] = useState('')

  // 定义按钮点击事件处理函数
  const handleModelTest = async () => {
    setLoadings([true]);
    setBtnTxt("测试中")
    if (editInfo === '') {
      setLoadings([false]);
      setBtnTxt("开始测试");
      message.warning('请输入测试备注!', 2);
      return;
    }
    if (fileList.length == 0) {
      setLoadings([false]);
      setBtnTxt("开始测试");
      message.warning('请至少上传一张图片!', 2);
      return;
    }
    let imageCodes = []
    for (const fl of fileList) {
      imageCodes.push(fl.thumbUrl)
    }
    try {
      const response = await fetch(baseUrl + '/back/model/testModel', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          'token': `${getCookie('token')}`
        },
        body: JSON.stringify({
          modelId: editId,
          modelTestText: editInfo,
          modelTester: localStorageGetItem('userName'),
          imageCodes: imageCodes,
        })
      });

      if (response.ok) {
        // 请求成功
        const data = await response.json();
        // 处理响应数据
        if (data.code === 200) {
          message.success(data.msg, 2)
          const dectectRes = JSON.parse(data.data);
          const details = dectectRes.details;
          let bs64 = []
          for (const bs of details) {
            bs64.push(bs.image_base64)
          }
          setBase64Array(bs64);
          let lgs = []
          const resLogs = dectectRes.logs;
          for (const lg of resLogs) {
            const tlg = lg.split(':')
            lgs.push(tlg[tlg.length - 1])
          }
          setLogResArray(lgs)
          setShowResImages(true)
        }
        else {
          message.warning(data.msg, 2);
        }
      } else {
        // 请求失败
        console.error('Error:', response.status);
      }
    } catch (error) {
      console.error('Error:', error);
    }
    setBtnTxt("开始测试");
    setLoadings([false]);
    setIsModalOpen(false);
  };



  const columns: ColumnsType<DataType> = [
    {
      title: "序号",
      dataIndex: "index",
      key: "index",
      render: (_, _record, index) => <span>{index + 1}</span>,
    },
    {
      title: "模型名称",
      dataIndex: "modelName",
      key: "modelName",
    },
    {
      title: "模型类型",
      dataIndex: "modelType",
      key: "modelType",
      render: (text) => {
        // 根据 text 的值分配不同的 Tag 样式
        if (text === '目标检测') {
          return <Tag color="blue">{text}</Tag>;
        } else if (text === '语义分割') {
          return <Tag color="green">{text}</Tag>;
        } else if (text === '综合识别') {
          return <Tag color="yellow">{text}</Tag>;
        } else if (text === '摆放检测') {
          return <Tag color="pink">{text}</Tag>;
        }
        else if (text === '时序预测') {
          return <Tag color="purple">{text}</Tag>;
        } else {
          // 如果 text 不匹配上述条件，则返回默认样式的 Tag
          return <Tag>{text}</Tag>;
        }
      }
    },
    {
      title: "模型描述",
      dataIndex: "modelDesc",
      key: "modelDesc",
    },
    {
      title: "模型测试接口地址",
      dataIndex: "modelApi",
      key: "modelApi",
    },
    {
      title: "模型参数说明",
      dataIndex: "modelParamDesc",
      key: "modelParamDesc",
    },
    {
      title: "加入时间",
      key: "createTime",
      dataIndex: "createTime",
    },
    {
      title: "最后修改时间",
      key: "updateTime",
      dataIndex: "updateTime",
    },
    {
      title: "操作",
      key: "action",
      render: (_, record) => (
        <Space size="middle">
          <Button type="default" onClick={(e) => showModalEdit(record, e)} className="edit-button">
            测试模型
          </Button>
        </Space>
      ),
    },
    {
      title: "id",
      dataIndex: "id",
      key: "id",
      className: 'hiddenColumn'
    }
  ];

  const selInfoDetail = async () => {
    try {
      setPageLoading(true);
      const response = await fetch(baseUrl + '/back/model/getModelLikeSth?info=' + selInfo + '&sth=' + selInfo2, {
        method: 'GET',
        headers: {
          'Content-Type': 'application/json',
          'token': `${getCookie('token')}`
        }
      });
      setPageLoading(false);
      if (response.ok) {
        // 请求成功
        const data = await response.json();
        // 处理响应数据
        if (data.code === 200) {
          const dataWithKeys = data.data.map((item: { id: { toString: () => any; }; }) => ({ ...item, key: item.id.toString() }));
          setData(dataWithKeys);
          setListNum(dataWithKeys.length);
          message.success(data.msg, 1);
        }
        else {
          message.warning(data.msg, 1);
        }
      } else {
        // 请求失败
        console.error('Error:', response.status);
      }
    } catch (error) {
      console.error('Error:', error);
    }
  };

  const SubmitButton = ({ form }: { form: FormInstance }) => {
    const [submittable, setSubmittable] = React.useState(false);

    // Watch all values
    const values = Form.useWatch([], form);

    React.useEffect(() => {
      form.validateFields({ validateOnly: true }).then(
        () => {
          setSubmittable(true);
        },
        () => {
          setSubmittable(false);
        },
      );
    }, [values]);

    return (
      <Button type="primary" htmlType="submit" disabled={!submittable} onClick={selInfoDetail}>
        查询
      </Button>
    );
  };

  const handleSelInfoChange = (event: { target: { value: React.SetStateAction<string>; }; }) => {
    setSelInfo(event.target.value);
  };

  const handleSelInfo2Change = (e: RadioChangeEvent) => {
    setSelInfo2(e.target.value);
  };

  const handleEditInfoChange = (event: React.ChangeEvent<HTMLInputElement>) => {
    setEditInfo(event.target.value);
  };

  const [showResImages, setShowResImages] = useState(false);
  const [base64Array, setBase64Array] = useState<string[]>([]);
  const [logResArray, setLogResArray] = useState<string[]>([]);


  const handleResImageCancel = () => {
    setShowResImages(false);
  };

  const [previewOpen, setPreviewOpen] = useState(false);
  const [previewImage, setPreviewImage] = useState('');
  const [previewTitle, setPreviewTitle] = useState('');
  const [fileList, setFileList] = useState<UploadFile[]>([]);

  const handleCancelUpload = () => setPreviewOpen(false);

  const handlePreview = async (file: UploadFile) => {
    if (!file.url && !file.preview) {
      file.preview = await getBase64(file.originFileObj as RcFile);
    }

    setPreviewImage(file.url || (file.preview as string));
    setPreviewOpen(true);
    setPreviewTitle(file.name || file.url!.substring(file.url!.lastIndexOf('/') + 1));
  };

  const props: UploadProps = {
    beforeUpload: (file) => {
      const isJPGPNG = file.type === 'image/jpg' || file.type === 'image/jpeg' || file.type === 'image/png';
      if (!isJPGPNG) {
        message.warning("只能上传jpg或png格式的图片", 1.5);
      }
      return isJPGPNG || Upload.LIST_IGNORE;
    }
  };

  const handleChange: UploadProps['onChange'] = async ({ fileList: newFileList }) => {
    setFileList(newFileList);
  };

  const uploadButton = (
    <div>
      <PlusOutlined />
      <div style={{ marginTop: 8 }}>Upload</div>
    </div>
  );

  return (
    <>
      <LoadingIndicator loading={pageLoading} />
      <Form form={form} name="validateOnly" layout="inline" autoComplete="off">
        <Form.Item>
          <Radio.Group size="middle" value={selInfo2} onChange={handleSelInfo2Change}>
            <Radio.Button value="模型名称">按模型名称查询</Radio.Button>
            <Radio.Button value="模型类型">按模型类型查询</Radio.Button>
          </Radio.Group>
        </Form.Item>
        <Form.Item name="name" label="" rules={[{ required: true, message: "查找字段内容不得为空,如不想查找请点击重置!" }]}>
          <Input placeholder="(选择其中一个标准模糊查询）" value={selInfo} onChange={handleSelInfoChange} />
        </Form.Item>
        <Form.Item>
          <Space>
            <SubmitButton form={form} />
            <Button htmlType="reset">重置</Button>
          </Space>
        </Form.Item>
        <Tag bordered={true} color="green" className="total-tag">
          共{listNum}条记录
        </Tag>
        <Button type="link" onClick={fetchData}>查询所有</Button>
      </Form>
      <Modal title="请填入模型测试所需的材料" open={isModalOpen} onOk={handleModelTest} onCancel={handleCancel} width="60%"
        footer={[
          <Button key="back" onClick={handleCancel}>
            取消
          </Button>,
          <Button key="submit" type="primary" loading={loadings[0]} onClick={handleModelTest}>
            {testBthTxt}
          </Button>,
        ]}>
        <Form>
          <Form.Item
            label="测试备注"
            name="1"
            rules={[{ required: true, message: "该字段不可为空！" }]}
          >
            <Input size="large" style={{ width: '350px' }} value={editInfo} onChange={handleEditInfoChange} placeholder="（不可为空）" />
          </Form.Item>
          <h1>请上传要测试的图片（最多8张，且图片须为jpg或png格式）：</h1>
          <Upload {...props}
            action={baseUrl + "/sys/testProject/fakeImageUpload"}
            listType="picture-card"
            fileList={fileList}
            onPreview={handlePreview}
            onChange={handleChange}
          >
            {fileList.length >= 8 ? null : uploadButton}
          </Upload>
          <Modal open={previewOpen} title={previewTitle} footer={null} onCancel={handleCancelUpload}>
            <img alt="example" style={{ width: '100%' }} src={previewImage} />
          </Modal>
        </Form>
      </Modal>
      <Modal title="测试结果" open={showResImages} okText="确定" width="60%"
        cancelText="取消" onOk={handleResImageCancel} onCancel={handleResImageCancel}>
        {base64Array.map((base64, index) => (
          <Card
            key={index}
            hoverable
            style={{ display: 'inline-block', width: 180, height: 350, marginRight: 30, marginBottom: 30, verticalAlign: 'middle' }}
            cover={<Image src={base64} style={{ width: 180, height: 180 }} />}
          >
            <Meta title="" description={logResArray[index]} />
          </Card>
        ))}
      </Modal>
      <Modal title="请填入模型测试所需的材料" open={lstmModalOpen}
        width="60%" onOk={handleLstmTestOk} onCancel={handleLstmTestCancel}
        footer={[
          <Button key="back" onClick={handleLstmTestCancel}>
            取消
          </Button>,
          <Button key="submit" type="primary" loading={loadings[0]} onClick={handleLstmTestOk}>
            {testBthTxt}
          </Button>,
        ]}
      >
        <Form>
          <Form.Item
            label="测试备注"
            name="11"
            rules={[{ required: true, message: "该字段不可为空！" }]}
          >
            <Input size="large" style={{ width: '350px' }} value={editInfo} onChange={handleEditInfoChange} placeholder="（不可为空）" />
          </Form.Item>
          <Form.Item
            label="单车停放区域当前气温"
            name="22"
            rules={[{ required: true, message: "请填写正确气温数值！", type: 'number' }]}
          >
            <InputNumber size="large" style={{ width: '350px' }} value={zoneTemp} onChange={handleLstmInfo1Change} placeholder="默认为0（整数）" />
          </Form.Item>
          <Form.Item
            label="单车停放区域当前天气类型"
            name="33"
            rules={[{ required: true, message: "请选择正确天气类型！", type: 'number' }]}
          >
            <Select
              showSearch
              placeholder="选择天气类型"
              optionFilterProp="zoneWeather"
              onChange={handleLstmInfo2Change}
              filterOption={(input, option) =>
                (option?.label ?? '').toLowerCase().includes(input.toLowerCase())
              }
              options={[
                {
                  value: 0,
                  label: '晴',
                },
                {
                  value: 1,
                  label: '多云',
                },
                {
                  value: 2,
                  label: '阴',
                },
                {
                  value: 3,
                  label: '阵雨',
                },
                {
                  value: 4,
                  label: '雷阵雨',
                },
                {
                  value: 5,
                  label: '雷阵雨伴有冰雹',
                },
                {
                  value: 6,
                  label: '雨',
                },
                {
                  value: 7,
                  label: '雨夹雪',
                },
                {
                  value: 8,
                  label: '小雨',
                },
                {
                  value: 9,
                  label: '中雨',
                },
                {
                  value: 10,
                  label: '大雨',
                },
                {
                  value: 11,
                  label: '暴雨',
                },
                {
                  value: 12,
                  label: '大暴雨',
                },
                {
                  value: 13,
                  label: '特大暴雨',
                },
                {
                  value: 14,
                  label: '雪',
                },
                {
                  value: 15,
                  label: '阵雪',
                },
                {
                  value: 16,
                  label: '小雪',
                },
                {
                  value: 17,
                  label: '中雪',
                },
                {
                  value: 18,
                  label: '大雪',
                },
                {
                  value: 19,
                  label: '暴雪',
                },
                {
                  value: 20,
                  label: '雾',
                },
                {
                  value: 21,
                  label: '冻雨',
                },
                {
                  value: 22,
                  label: '沙尘暴',
                },
                {
                  value: 23,
                  label: '小雨-中雨',
                },
                {
                  value: 24,
                  label: '中雨-大雨',
                },
                {
                  value: 25,
                  label: '大雨-暴雨',
                },
                {
                  value: 26,
                  label: '暴雨-大暴雨',
                },
                {
                  value: 27,
                  label: '大暴雨-特大暴雨',
                },
                {
                  value: 28,
                  label: '小雪-中雪',
                },
                {
                  value: 29,
                  label: '中雪-大雪',
                },
                {
                  value: 30,
                  label: '大雪-暴雪',
                },
                {
                  value: 31,
                  label: '浮尘',
                },
                {
                  value: 32,
                  label: '扬沙',
                },
                {
                  value: 33,
                  label: '强沙尘暴',
                },
                {
                  value: 34,
                  label: '霾',
                },
              ]}
            />
          </Form.Item>
          <Form.Item
            label="单车停放区域当前最大风力"
            name="44"
            rules={[{ required: true, message: "请填写正确风力数值！", type: 'number' }]}
          >
            <InputNumber size="large" style={{ width: '350px' }} value={zonePower} onChange={handleLstmInfo3Change} placeholder="默认为0（整数）" />
          </Form.Item>
          <Form.Item
            label="单车停放区域当天是否为节假日"
            name="55"
            rules={[{ required: true, message: "请选择正确选项！", type: 'number' }]}
          >
            <Select
              showSearch
              placeholder="选择是否节假日"
              optionFilterProp="isHoliday"
              onChange={handleLstmInfo4Change}
              filterOption={(input, option) =>
                (option?.label ?? '').toLowerCase().includes(input.toLowerCase())
              }
              options={[
                {
                  value: 0,
                  label: '否',
                },
                {
                  value: 1,
                  label: '是',
                },
              ]}
            />
          </Form.Item>
          <Form.Item
            label="单车停放区域当天是否为周末"
            name="66"
            rules={[{ required: true, message: "请选择正确选项！", type: 'number' }]}
          >
            <Select
              showSearch
              placeholder="选择是否周末"
              optionFilterProp="isWeekend"
              onChange={handleLstmInfo5Change}
              filterOption={(input, option) =>
                (option?.label ?? '').toLowerCase().includes(input.toLowerCase())
              }
              options={[
                {
                  value: 0,
                  label: '否',
                },
                {
                  value: 1,
                  label: '是',
                },
              ]}
            />
          </Form.Item>
          <Form.Item
            label="单车停放区域方圆1公里区域数"
            name="77"
            rules={[{ required: true, message: "请填写正确数值！", type: 'number' }]}
          >
            <InputNumber size="large" style={{ width: '350px' }} value={nearbyZoneNum} onChange={handleLstmInfo6Change} placeholder="默认为0" />
          </Form.Item>
          <Form.Item
            label="单车停放区域近邻区域单车流量数"
            name="88"
            rules={[{ required: true, message: "请填写正确数值！", type: 'number' }]}
          >
            <InputNumber size="large" style={{ width: '350px' }} value={k1ZoneFlow} onChange={handleLstmInfo7Change} placeholder="默认为0" />
          </Form.Item>
          <Form.Item
            label="单车停放区域近邻区域单车流量数"
            name="99"
            rules={[{ required: true, message: "请填写正确数值！", type: 'number' }]}
          >
            <InputNumber size="large" style={{ width: '350px' }} value={k2ZoneFlow} onChange={handleLstmInfo8Change} placeholder="默认为0" />
          </Form.Item>
          <Form.Item
            label="单车停放区域近邻区域单车流量数"
            name="00"
            rules={[{ required: true, message: "请填写正确数值！", type: 'number' }]}
          >
            <InputNumber size="large" style={{ width: '350px' }} value={k3ZoneFlow} onChange={handleLstmInfo9Change} placeholder="默认为0" />
          </Form.Item>
        </Form>
      </Modal>
      <Table<DataType> columns={columns} dataSource={data} />
    </>
  );
};

export default Model;